05779ceabcf73bb74c1b533e4eb4c502a3bacc8b,src/heros/alias/FieldSensitiveIFDSSolver.java,FieldSensitiveIFDSSolver,processCall,#PathEdge#,209
Before Change
for (N returnSiteN : returnSiteNs) {
FlowFunction<FieldRef, D> callToReturnFlowFunction = flowFunctions.getCallToReturnFlowFunction(n, returnSiteN);
for(AnnotatedFact<FieldRef, D> d3: computeCallToReturnFlowFunction(callToReturnFlowFunction, d1, d2))
propagate(d1, returnSiteN, d3.getFact(), n, false);
}
}
After Change
* @param edge an edge whose target node resembles a method call
*/
private void processCall(PathEdge<N,D> edge) {
final D d1 = edge.factAtSource();
final N n = edge.getTarget(); // a call node; line 14...
logger.trace("Processing call to {}", n);
final D d2 = edge.factAtTarget();
assert d2 != null;
Collection<N> returnSiteNs = icfg.getReturnSitesOfCallAt(n);
//for each possible callee
Collection<M> callees = icfg.getCalleesOfCallAt(n);
for(M sCalledProcN: callees) { //still line 14
//compute the call-flow function
FlowFunction<FieldRef, D> function = flowFunctions.getCallFlowFunction(n, sCalledProcN);
Set<AnnotatedFact<FieldRef, D>> res = computeCallFlowFunction(function, d1, d2);
Collection<N> startPointsOf = icfg.getStartPointsOf(sCalledProcN);
//for each result node of the call-flow function
for(AnnotatedFact<FieldRef, D> d3: res) {
//for each callee's start point(s)
for(N sP: startPointsOf) {
//create initial self-loop
D abstractStartPointFact = d3.getFact().cloneWithAccessPath(new AccessPath<FieldRef>());
propagate(new PathEdge<>(abstractStartPointFact, sP, abstractStartPointFact), n, false); //line 15
}
//register the fact that <sp,d3> has an incoming edge from <n,d2>
//line 15.1 of Naeem/Lhotak/Rodriguez
IncomingEdge<D, N> incomingEdge = new IncomingEdge<D, N>(d3.getFact(),n,d1,d2);
if (!addIncoming(sCalledProcN, incomingEdge))
continue;
resumeEdges(sCalledProcN, d3.getFact());
registerInterestedCaller(sCalledProcN, incomingEdge);
//line 15.2
Set<SummaryEdge<D, N>> endSumm = endSummary(sCalledProcN, d3.getFact());
//still line 15.2 of Naeem/Lhotak/Rodriguez
//for each already-queried exit value <eP,d4> reachable from <sP,d3>,
//create new caller-side jump functions to the return sites
//because we have observed a potentially new incoming edge into <sP,d3>
if (endSumm != null)
for(SummaryEdge<D, N> summary: endSumm) {
if(AccessPathUtil.isPrefixOf(summary.getSourceFact(), d3.getFact())) {
Optional<D> d4 = AccessPathUtil.applyAbstractedSummary(d3.getFact(), summary);
if(d4.isPresent()) {
//for each return site
for(N retSiteN: returnSiteNs) {
//compute return-flow function
FlowFunction<FieldRef, D> retFunction = flowFunctions.getReturnFlowFunction(n, sCalledProcN, summary.getTargetStmt(), retSiteN);
//for each target value of the function
for(AnnotatedFact<FieldRef, D> d5: computeReturnFlowFunction(retFunction, d4.get(), n)) {
D d5p_restoredCtx = restoreContextOnReturnedFact(d2, d5.getFact());
propagate(new PathEdge<>(d1, retSiteN, d5p_restoredCtx), n, false);
}
}
}
}
}
}
}
//line 17-19 of Naeem/Lhotak/Rodriguez
//process intra-procedural flows along call-to-return flow functions
for (N returnSiteN : returnSiteNs) {
FlowFunction<FieldRef, D> callToReturnFlowFunction = flowFunctions.getCallToReturnFlowFunction(n, returnSiteN);
for(AnnotatedFact<FieldRef, D> d3: computeCallToReturnFlowFunction(callToReturnFlowFunction, d1, d2))
propagate(new PathEdge<>(d1, returnSiteN, d3.getFact()), n, false);
}
}